/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tp_imag.service.impl;

import tp_imag.model.*;
import ij.ImagePlus;
import ij.io.FileSaver;
import ij.plugin.filter.Convolver;
import ij.process.ByteProcessor;
import ij.process.ImageConverter;
import java.awt.Image;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ConvolveOp;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import javax.imageio.ImageIO;
import tp_imag.model.ActualImage;
import tp_imag.model.EcualizadorImagen;
import tp_imag.model.Filter;
import tp_imag.service.ImageProcessor;
import java.util.Vector;
import org.apache.log4j.Logger;

/**
 *
 * @author Administrador
 */
public class ImageProcessorImpl implements ImageProcessor {

    static Logger logger = Logger.getLogger(Recorrido.class);
    private ColorSpace espacioGrises;
    private ColorConvertOp ccop;


    public BufferedImage openImage(String imagePath) {
        BufferedImage buf = null;
        try {
            buf = ImageIO.read(new File(imagePath));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return resizeImage(buf,640,480);
        //return buf;
    }
    
    public BufferedImage resizeImage(BufferedImage imagenOriginal,int x, int y) {
    	
    	 ImagePlus nueva1 = new ImagePlus();
    	 
        try {
        	ij.process.ColorProcessor bp = new ij.process.ColorProcessor(imagenOriginal);
        	bp.resize(x, y);        	
        	nueva1.setProcessor("resize", bp);           
          
        	
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return nueva1.getBufferedImage();
    }


    public BufferedImage filterImage(BufferedImage source, Collection<Filter> filters) {
        //Inicializamos
    	
        espacioGrises = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        ccop = new ColorConvertOp (espacioGrises, null);

        BufferedImage destino = ccop.filter(source, null);
        BufferedImage img = destino;

        boolean primero = true;

        for (Filter filter: filters) {
            img = filter(img, filter, primero);
            primero = false;
        }
        if (primero) {
            img = null;
        }
        
        return img;
    }

    private BufferedImage filter(BufferedImage source, Filter filter, boolean primero) {
        try {
            //BufferedImage nuevaProbando = new BufferedImage(source.getWidth(),source.getHeight(),BufferedImage.TYPE_BYTE_GRAY);

            ccop = new ColorConvertOp (espacioGrises, null);

            BufferedImage destino = null;
            if (primero) {
                destino = source;
            } else {
                destino = openImage("img_temp/filt.jpg");                
            }

            float [] values = filter.getValues();               
            
            
            ByteProcessor out = null;  
            ImagePlus nueva = new ImagePlus();
            ij.process.ColorProcessor bp = new ij.process.ColorProcessor(destino);
            
           
            if (values==null){
            	         if (filter.getName()=="Canny"){
			                Canny_ test = new Canny_();  
			                out = test.canny(bp);
			              
			                nueva.setProcessor("filtros", out);
            	         }else if (filter.getName()=="Sobel"){
            	        	 
            	        	 
            	        	 bp.findEdges();
            	        	 nueva.setProcessor("filtros", bp);
            	        	 
            	        	     	        	 
            	         }
            }
            else{
            	
            	bp.convolve(values, 3, 3);     
            	nueva.setProcessor("filtros", bp);
            
            }
            	
            	
           
            //bp.noise(100000);
            

            //Image im = bp.createImage();

            
            
            //ImageConverter icNuevo = new ImageConverter(nueva);
            //icNuevo.convertToGray8();
            FileSaver fs = new FileSaver(nueva);
            fs.saveAsJpeg("img_temp/filt.jpg");

                        
            return nueva.getBufferedImage();
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }        
    }

        /* por default se binariza sin ecualizacion */
    public BufferedImage binarizeImage(BufferedImage source, int umbral) {
        logger.debug("Binarizando: ancho="+source.getWidth()+ " alto="+source.getHeight());
        espacioGrises = ColorSpace.getInstance(ColorSpace.CS_GRAY);
	ccop = new ColorConvertOp (espacioGrises, null);

        BufferedImage destino = ccop.filter(source, null);
        //BufferedImage nuevaProbando = new BufferedImage(source.getWidth(),source.getHeight(),BufferedImage.TYPE_BYTE_GRAY);

        ByteProcessor bp = new ByteProcessor(destino);
        //ByteProcessor bp = new ByteProcessor(destino);

        bp.threshold(umbral);
        ActualImage.getInstance().setBinarizedBP(bp);

        ImagePlus nueva = new ImagePlus();
        nueva.setProcessor("binarizada", bp);
        ImageConverter icNuevo = new ImageConverter(nueva);
        icNuevo.convertToGray8();

        FileSaver fs = new FileSaver(nueva);
        fs.saveAsJpeg("img_temp/binar.jpg");

        return nueva.getBufferedImage();
    }

    /* por default se binariza sin ecualizacion */
    public BufferedImage binarizeImage(BufferedImage source) {
        return binarizeImage(source, false);
    }

    public BufferedImage binarizeImage(BufferedImage source, boolean realizaEcualizacion) {
        logger.debug("Binarizando: ancho="+source.getWidth()+ " alto="+source.getHeight());
        espacioGrises = ColorSpace.getInstance(ColorSpace.CS_GRAY);
	ccop = new ColorConvertOp (espacioGrises, null);

        BufferedImage destino = ccop.filter(source, null);
        //BufferedImage nuevaProbando = new BufferedImage(source.getWidth(),source.getHeight(),BufferedImage.TYPE_BYTE_GRAY);


        ByteProcessor bp = null;
        if (realizaEcualizacion) {
            bp = equalizeImage(destino);
        } else {
            bp = new ByteProcessor(destino);
        }
        
        //ByteProcessor bp = new ByteProcessor(destino);
        


        bp.autoThreshold();
        ActualImage.getInstance().setBinarizedBP(bp);

        ImagePlus nueva = new ImagePlus();
        nueva.setProcessor("binarizada", bp);
        ImageConverter icNuevo = new ImageConverter(nueva);
        icNuevo.convertToGray8();

        FileSaver fs = new FileSaver(nueva);
        fs.saveAsJpeg("img_temp/binar.jpg");

        return nueva.getBufferedImage();
        //FileSaver fs = new FileSaver(nueva);
        //fs.saveAsJpeg(dirArchivo+"/"+nombreArchivo+"_"+filtro+".jpg");

    }

    public Vector<CoordenadaTransformada> vectorizeImage(BufferedImage source, String path) throws IOException {
        BuscarPuntos buscador = new BuscarPuntos();

        espacioGrises = ColorSpace.getInstance(ColorSpace.CS_GRAY);
	ccop = new ColorConvertOp (espacioGrises, null);

        BufferedImage destino = ccop.filter(source, null);
        ByteProcessor bp = new ByteProcessor(destino);
        bp.autoThreshold();
        return buscador.execute(bp, path);
    }

    private ByteProcessor equalizeImage(BufferedImage image) {
        EcualizadorImagen eq = new EcualizadorImagen(image);
        ByteProcessor img = eq.equalizeImage();
        return img;
    }
    
}


